/*********************************************************************\
*                                                                     *
*         Jamper - Java XML mapper (visual XSLT generator)            *
*                Copyright (C) 2005 Filip Pavlovic                    *
*                    sqba@users.sourceforge.net                       *
*                                                                     *
*  This program is free software; you can redistribute it and/or      *
*  modify it under the terms of the GNU General Public License        *
*  as published by the Free Software Foundation; either version 2     *
*  of the License, or (at your option) any later version.             *
*                                                                     *
*  This program is distributed in the hope that it will be useful,    *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of     *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
*  GNU General Public License for more details.                       *
*                                                                     *
*  You should have received a copy of the GNU General Public License  *
*  along with this program; if not, write to the Free Software        *
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston,             *
*  MA 02111-1307, USA.                                                *
*                                                                     *
\*********************************************************************/


package sqba.jamper;


import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;

import javax.swing.AbstractAction;
//import javax.swing.JCheckBoxMenuItem;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


//import org.xml.sax.InputSource;

import sqba.jamper.map.object.IMapObject;
import sqba.jamper.map.output.XSLTRenderer;
import sqba.jamper.map.tree.MapperTreeNode;
//import sqba.jamper.map.tree.MapperTree;
//import sqba.jamper.map.tree.MapperTreeNode;
//import sqba.jamper.map.tree.model.SAXTreeModel;
import sqba.jamper.util.DOMUtils;
import sqba.jamper.util.EncOptManager;
import sqba.jamper.util.XMLMapperInit;
import sqba.jamper.util.XMLNmsManager;


/**
 * Java XML Mapper - Jamper
 *
 * @author	Filip Pavlovic
 * @version	1.0
 */
public class JamperFrame extends JFrame
{
    public static int _appWidth  = 640;
    public static int _appHeight = 480;

    public static JamperFrame _instance = null;

    //private File _directory = new File(".");
	private String		_testFile		= "";

	private MapView		_mapView;
	private JTextArea	_outputXSL;
	private JTextArea	_descriptionView;
	private OptionPanel _optionPanel;
//	private JTextArea	_outputTest;
	private JEditorPane _htmlView;
	private JTextField 	_menuRuleName;
//	private MapperTree	_outputXSLTree;
//	private MapperTree	_outputTestTree;
	//private JTextArea	_license;

	private String		_xslt			= "";
	private Thread		_myThread		= null;

	private JMenu		_contextMenu	= null;
	private JMenuBar	_menuBar		= null;

	private MyTabbedPane _tabPane = null;

	public static URL	_documentBase = null;
	public static String	_register	= null;	
	public static String	_cpid		= null;
	public static String	_feed		= null;
	public static String	_NmsURL		= null;

    class MyOptionsMenu extends JMenu
	{
    	public MyOptionsMenu()
    	{
			super("Options");

	        /*JCheckBoxMenuItem cbMenuItem = new JCheckBoxMenuItem("Auto render");
	        cbMenuItem.addActionListener(new AbstractAction() {
		        public void actionPerformed(ActionEvent e) {
		            //boolean status = ((JCheckBoxMenuItem)e.getSource()).isSelected();
					//_mapObjView.setAutoRender(status);
		            //ToolTipManager.sharedInstance().setEnabled(status);
		        }
		    });
		    cbMenuItem.setSelected(_mapView._mapObjView.getAutoRender());
	        this.add(cbMenuItem);
	        ///////////////////////////////////////////////////////////////////////////
	
			cbMenuItem = new JCheckBoxMenuItem("Show output values");
	        cbMenuItem.addActionListener(new AbstractAction() {
		        public void actionPerformed(ActionEvent e) {
		            //boolean status = ((JCheckBoxMenuItem)e.getSource()).isSelected();
					//_dstTree.setShowValues(status);
		            //ToolTipManager.sharedInstance().setEnabled(status);
		        }
		    });
		    cbMenuItem.setSelected(true);//_dstTree.getShowValues());
			this.add(cbMenuItem);
	        this.addSeparator();*/

			// Look And Feel sub-menu
	        JMenu lfMenu = new JMenu("Look And Feel");
	        XMLMapperInit.initLookAndFeelMenu(lfMenu, JamperFrame.this);
	        this.add(lfMenu);
		}
	}

    class MyHelpMenu extends JMenu
	{
    	public MyHelpMenu()
    	{
			super("Help");

			JMenuItem menuItem;
	
			menuItem = new JMenuItem("About...");
	    	menuItem.addActionListener(new AbstractAction() {
		        public void actionPerformed(ActionEvent e) {
		        	//XMLMapperInit.showAboutDlg();
					JOptionPane.showMessageDialog(null,
						"Filip Pavlovic\nsqba@users.sourceforge.net\n" + 
						"http://jamper.sourceforge.net",
						"Jamper - Java XML Mapper",
						JOptionPane.PLAIN_MESSAGE,
						XMLMapperInit.loadIcon(XMLMapperInit.ICON_APP));
		        }
		    });
			this.add(menuItem);
		}
	}

    class MyMenuBar extends JMenuBar
	{
    	public MyMenuBar()
    	{
    		
    		JLabel menuRuleLabel = new JLabel();
    		_menuRuleName = new JTextField();
    		
    		menuRuleLabel.setText("Rule Name : ");
    		_menuRuleName.setText("Untitled Rule");
    		
    		//menuRuleName.setBorder(arg0)
			
    		JButton menuSaveButton;
			menuSaveButton = new JButton("Save Rule");
	    	menuSaveButton.addActionListener(new AbstractAction() {
		        public void actionPerformed(ActionEvent e) {
		        	
		        	if(null != _mapView) _mapView._objectPanel.render(); 
		        	
		        	String ret = "Connection Failed";
		        	
		        	HttpClient client = new HttpClient();
		            client.getParams().setParameter("http.useragent", "Test Client");

		            BufferedReader br = null;

		            PostMethod method = new PostMethod(_register);
/*
		            String srcXML, dstXML;
		            srcXML = dstXML = "";
		            try {
		            	DefaultMutableTreeNode srcRoot = _mapView._srcTree.getRootNode();
		            	DefaultMutableTreeNode dstRoot = _mapView._dstTree.getRootNode();

		            	DocumentBuilderFactory factory =   DocumentBuilderFactory.newInstance();
		            	DocumentBuilder builder;

		            	builder = factory.newDocumentBuilder();
		            	//now to create the document object that will house the tree.
		            	Document doc = builder.newDocument();

		            	doc.appendChild((Element)srcRoot);
		            	srcXML = DOMUtils.renderXMLString(doc);
		            	doc.replaceChild((Element)dstRoot, (Element)srcRoot);
		            	dstXML = DOMUtils.renderXMLString(doc);

		            } catch (ParserConfigurationException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
		            */
		            NameValuePair[] data = {
		        	          new NameValuePair("RuleName", _menuRuleName.getText() ),
		        	          new NameValuePair("Description", _descriptionView.getText() ),
		        	          new NameValuePair("XSL", _outputXSL.getText()),
		        	          new NameValuePair("CPID", _cpid),
		        	          new NameValuePair("MAP", _mapView._objectPanel.getMap().toString()),
		        	          new NameValuePair("FEED", _feed),
		        	          new NameValuePair("NMS", XMLNmsManager.getDataXML()),
		        	          new NameValuePair("ENC", ""+EncOptManager.getValue())
		        	    //      new NameValuePair("srcXML", srcXML),
		        	    //      new NameValuePair("dstXML", dstXML)
		        	          
		        	        };
		        	method.setRequestBody(data);
		            
		            try{
		              int returnCode = client.executeMethod(method);
		              ret = method.getResponseBodyAsString();
		              
		            } catch (Exception ex) {
		              System.err.println(ex);
		            } finally {
		              method.releaseConnection();
		              if(br != null) try { br.close(); } catch (Exception fe) {}
		            }
		        	
		            // response
					JOptionPane.showMessageDialog(null,
							ret,
						"Jamper - Java XML Mapper",
						JOptionPane.PLAIN_MESSAGE,
						XMLMapperInit.loadIcon(XMLMapperInit.ICON_APP));
		        }
		    });
	    	
	    	this.add( menuRuleLabel );
	    	this.add( _menuRuleName );
	    	this.add( menuSaveButton );
	    	this.add(_mapView.getMenu());
	    	//this.add(new MyHelpMenu());
	    	//this.add(new MyOptionsMenu());
			
		}
	}

    class MyTabbedPane extends JTabbedPane
	{
    	public MyTabbedPane()
    	{
    		this.addTab("Option",			XMLMapperInit.loadIcon("html.gif"), new JScrollPane(_optionPanel));
    		this.addTab("Map View",			XMLMapperInit.loadIcon("properties.gif"), _mapView);
	        this.addTab("XSLT View",		XMLMapperInit.loadIcon("cube.gif"), new JScrollPane(_outputXSL));
	        
	        
//	        this.addTab("XSLT Tree",		new JScrollPane(_outputXSLTree));
//	        this.addTab("Test Output",		new JScrollPane(_outputTest));
//	        this.addTab("Test Output Tree",	new JScrollPane(_outputTestTree));
	        //this.addTab("HTML Output",		XMLMapperInit.loadIcon("html.gif"), new JScrollPane(_htmlView));
	        //this.addTab("License",		new JScrollPane(_license));
	
			this.addChangeListener(new ChangeListener(){
				public void stateChanged(ChangeEvent e) {
					//Component src = MyTabbedPane.this.getSelectedComponent();
					//System.out.println(src);
					if(0 != MyTabbedPane.this.getSelectedIndex())
						JamperFrame.this._mapView.render();
				}
			});
		}
	}

    public JamperFrame()
    {
        super("Java XML Mapper ");

        _instance = this;

		XMLMapperInit.initLookAndFeel();

		// Load application icon
		setIconImage(XMLMapperInit.loadIcon(XMLMapperInit.ICON_APP).getImage());

		// Create components
		_mapView		= new MapView(this);
		_outputXSL		= new JTextArea();
		_descriptionView	= new JTextArea("Description_here");
//		_outputTest		= new JTextArea();
//		_outputXSLTree	= new MapperTree(false);
//		_outputTestTree = new MapperTree(false);
		_htmlView		= new JEditorPane();
		_optionPanel	= new OptionPanel();
		
		//_license		= new JTextArea();

		_htmlView.setContentType("text/html");
//		_outputXSLTree.setShowValues(true);
//		_outputTestTree.setShowValues(true);
        
        _tabPane = new MyTabbedPane();
        _menuBar = new MyMenuBar();
        
        getContentPane().setLayout(new BorderLayout() );
        getContentPane().add(_menuBar, BorderLayout.NORTH);
        getContentPane().add(_tabPane, BorderLayout.CENTER);
        
        
		
		
    }

	/**
	 * Main function.
	 */
    public static void main(String[] args)
    {
        JamperFrame frame = new JamperFrame();
        //_instance = frame;

        if(args.length == 1)
        	frame.loadMap(args[0]);

        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        frame.pack();
        frame.setSize(_appWidth, _appHeight);
        frame.setVisible(true);
    }
    
    public Component getPane() { return this.getContentPane(); }
    //public JMenuBar	getMenuBar1() { return _menuBar; }

	/**
	 * Sets the file that contains test data.
	 *
	 * @param file File
	 */
	public void setTestFile(String uri)
	{
		_testFile = uri;
	}

	/**
	 * Separate thread that transforms the sample data
	 * using previously rendered XSLT and fills all
	 * related controls.
	 */
	private class OutputLoaderThread implements Runnable
	{
		public void run()
		{
			_outputXSL.setText(_xslt);
			_outputXSL.repaint();
			
			/*MapperTreeNode root = new MapperTreeNode("Loading...", _outputXSLTree);
			SAXTreeModel newModel = new SAXTreeModel(root);
			newModel.Load(new InputSource(new StringReader(_xslt)));
			_outputXSLTree.setModel(newModel);*/

			try {
				if(null != _testFile) {
					TransformerFactory tFactory = TransformerFactory.newInstance();
					StringReader in = new StringReader(_xslt);
					Transformer transformer = tFactory.newTransformer(new StreamSource(in));
					StringWriter out = new StringWriter();
					transformer.transform(new StreamSource(_testFile), new StreamResult(out));
//					_outputTest.setText(out.toString());
//					_outputTest.repaint();

//					MapperTreeNode root2 = new MapperTreeNode("Loading...", _outputTestTree);
//					SAXTreeModel newModel2 = new SAXTreeModel(root2);
//					newModel2.Load(new InputSource(new StringReader(out.toString())));
//					_outputTestTree.setModel(newModel2);

					_htmlView.setText(out.toString());
				}
			} catch(TransformerException e) {
				System.out.println(e);
				_htmlView.setText(e.getLocalizedMessage());
				//_htmlView.setText(e.toString());
	        //} catch(FileNotFoundException e) {
			//} catch(IOException e) {
			}

			//setSelectedIndex(1);
		}
	}

	public void setXSLT(String xslt)
	{
		_xslt = xslt;
		_outputXSL.setText(_xslt);
		_outputXSL.repaint();
		/*_myThread = new Thread(new OutputLoaderThread());
		_myThread.start();*/
	}

	public void objectSelected(IMapObject sel)
	{
		if(null != _contextMenu)
			_menuBar.remove(_contextMenu);

		_contextMenu = sel.getMenu();
		if(null != _contextMenu)
			_menuBar.add(_contextMenu);

		_menuBar.revalidate();
		_menuBar.repaint();
		
		_mapView._propView.objectSelected(sel);
	}
	
	public void loadMap(String filename)
	{
		XMLNmsManager.readFile(_NmsURL);
		_mapView.loadMap(filename);//, false);
	}
}
